#------------------------------------------------------------------------------#
#                                                                              #
#  Executive Targets                                                           #
#                                                                              #
#------------------------------------------------------------------------------#

#---------------------------------------------------
# Output directory tree
#---------------------------------------------------
ifdef OUTPUT_DIR
   OUTPUT_DIR_SL    = $(OUTPUT_DIR)/$(LIB_DIR)
   A_TOLINK_TMP     = $(foreach filename,$(A_LIBS),$(OUTPUT_DIR_SL)$(filename))
   OUTDIR_FULL      = $(OUTPUT_DIR)/$(OUTDIR)
   OUTPUT_FILE_TMP  = $(OUTPUT_DIR)/$(OUTPUT_FILENAME)
   LIB_FILENAME_TMP = $(OUTPUT_DIR_SL)/$(LIB_FILENAME)
   ROOT_DIR_PAT     = $(ROOT_DIR)
else
   OUTPUT_DIR_SL    =
   A_TOLINK_TMP     = $(A_LIBS)
   OUTDIR_FULL      = $(OUTDIR)
   OUTPUT_FILE_TMP  = $(OUTPUT_FILENAME)
   LIB_FILENAME_TMP = $(LIB_FILENAME)
   ROOT_DIR_PAT     =
endif

#---------------------------------------------------
# Varibles - file lists/dynamic targets
#---------------------------------------------------
ifneq ($(C_FILES),)
C_FILES_ARM   = $(C_FILES)
endif

O_ARM_FILES   = $(foreach filename, $(basename $(C_FILES_ARM)),  $(OUTPUT_DIR_SL)$(filename).o)

O_THUMB_FILES = $(foreach filename, $(basename $(C_FILES_TH_AR)),$(OUTPUT_DIR_SL)$(filename).o)

O_ASM_FILES   = $(foreach filename, $(basename $(ASM_FILES))    ,$(OUTPUT_DIR_SL)$(filename).o)

D_CFILES      = $(foreach filename, $(basename $(C_FILES_ARM)),  $(OUTPUT_DIR_SL)$(filename).d) \
                $(foreach filename, $(basename $(C_FILES_TH_AR)),$(OUTPUT_DIR_SL)$(filename).d)

ifdef ADD_DEL_EXT
ADD_DEL_FILES = $(foreach ext, $(ADD_DEL_EXT), \
                $(foreach filename, $(basename $(D_CFILES)),$(filename).$(ext)))
endif

D_ASMFILES    = $(foreach filename, $(basename $(ASM_FILES)), $(OUTPUT_DIR_SL)$(filename).d)

EXT_OBJ_TMP   = $(foreach filename,$(EXTRA_OBJECTS),$(OUTPUT_DIR_SL)$(filename))
O_TOLINK_TMP  = $(O_ARM_FILES) $(O_THUMB_FILES) $(O_ASM_FILES) $(EXT_OBJ_TMP)
ifdef WIN_PATH
O_TOLINK      = $(foreach ofile, $(O_TOLINK_TMP), "$(shell cygpath -w $(ofile))")
A_TOLINK      = $(foreach ofile, $(A_TOLINK_TMP), "$(shell cygpath -w $(ofile))")
else
O_TOLINK      = $(O_TOLINK_TMP)
A_TOLINK      = $(A_TOLINK_TMP)
endif

A_LIBS_P      = $(foreach dir,$(LIBS),$(dir)/$(LIB_FILENAME))

LIBS_CLEAN    = $(foreach dir,$(LIBS),$(dir)_CLEANTAG)

INCLUDES_DIRS = $(foreach flag,$(INCLUDES),$(INCLUDE_FLAG)$(flag))



default_target: help

.PHONY: default_target link compile depend lib libs $(A_LIBS)


#=============================
#
# link:
#
#=============================
ifdef WIN_PATH
   OUTPUT_FILE = "$(shell cygpath -w $(OUTPUT_FILE_TMP))"
else
   OUTPUT_FILE = $(OUTPUT_FILE_TMP)
endif
link: hello compile $(A_LIBS) link_text $(OUTDIR_FULL)
	@$(COL_LINK); echo -n $(DECO); $(COL_RESET);
	@echo  "Linking file ... $(OUTPUT_FILENAME)"
	@rm -f $(OUTPUT_FILENAME)
	$(LINK) $(LINK_FLAGS) $(O_TOLINK) $(A_TOLINK) $(GCC_LIBS)\
            -o $(OUTPUT_FILE) >$(OUTDIR_FULL)/link_out.txt
	$(INFO_OUTPUT_CMD)
	chmod 777 $(OUTDIR_FULL)
	@$(COL_DONE); echo $(DECO)"DONE! :) :) :)"; $(COL_RESET)

link_text:
	@$(MAKE) ball TEXT="Linking ..." -s COLOR_BALL="$(COL_LINK)"



#=============================
#
# libs:
#
#=============================
libs: hello compile_text $(A_LIBS)


#=============================
#
# lib:
#
#=============================
ifdef WIN_PATH
   OUT_LIB_FILE = "$(shell cygpath -w $(LIB_FILENAME_TMP))"
else
   OUT_LIB_FILE = $(LIB_FILENAME_TMP)
endif
lib: hello compile $(OUTDIR_FULL)
	@$(COL_LIB); echo -n $(DECO); $(COL_RESET);
	@echo "Archiving ... $(LIB_FILENAME) $(LIB_FILENAME)"
    ifdef OUTPUT_DIR
	@mkdir -p $(dir $(OUTPUT_DIR_SL)/$(LIB_FILENAME))
    endif
	$(ARCH) $(ARCH_OPTS) $(OUT_LIB_FILE) $(O_TOLINK) > /dev/null  


#=============================
#
# bin:
# all:
#
#=============================
all: bin $(SUMMARY)

bin: hello link
ifdef RAW_OUTPUT_CMD
	@$(COL_LINK); echo -n $(DECO); $(COL_RESET);
	@echo  "Generating raw binary file ... $(OUTPUT_RAWFILE)"
	$(RAW_OUTPUT_CMD)
	@$(COL_DONE); echo $(DECO)"DONE! :) :) :)"; $(COL_RESET)
endif


#=============================
#
# $(A_LIBS):
#
#=============================
$(A_LIBS):
	@echo
	@$(COL_LIB); echo -n $(DECO); $(COL_RESET);
	@echo "Going to create ... $(subst $(ROOT_DIR),<root>,$@)"
	@$(MAKE) -C $(subst $(OUTDIR),,$(dir $@)) lib NO_HELLO=1 NO_BALL=1 \
             LIB_DIR=$(subst $(OUTDIR)/,,$(dir $@))


#=============================
#
# compile:
#
#=============================

compile: hello compile_text depend $(O_ARM_FILES) $(O_THUMB_FILES) $(O_ASM_FILES)


compile_text:
	@$(MAKE) ball TEXT="Compiling ..." -s COLOR_BALL="$(COL_COMP)"




#=============================
#
# depend:
#
#=============================
ROOT_TIME := "$(shell date '+%Y-%m-%d %H:%M:%S')"
depend:
	@$(COL_COMP); echo -n $(DECO); $(COL_RESET); echo "Constructing/checking dependecy rules ..."
	@$(MAKE) -j depend_files MAKE_DEPEND=1 RIGHT_TIME=$(ROOT_TIME)

depend_files: $(D_CFILES) $(D_ASMFILES)


# include dependency rules:

ifneq ($(D_CFILES),)
-include $(D_CFILES)
endif
ifneq ($(D_ASMFILES),)
-include $(D_ASMFILES)
endif


#=============================
#
# $(O_ARM_FILES)
# $(O_THUMB_FILES)
# $(O_ASM_FILES)
#
#=============================
ifdef WIN_PATH
   SRC_FILE = "$(shell cygpath -w $<)"
else
   SRC_FILE = $<
endif
ifndef DEFAULT_OUTFILE
  ifdef WIN_PATH
     OUT_FILE = "$(shell cygpath -w $@)"
  else
     OUT_FILE = $@
  endif
else
     OUT_FILE =
endif


DBGFILEID = -DDBGID=d_$(basename $(notdir $1))

$(O_ARM_FILES): $(OUTPUT_DIR)%.o : $(ROOT_DIR_PAT)%.c
	@$(COL_COMP); echo -n $(DECO); $(COL_RESET); echo "Compiling ... $<"
    ifdef OUTPUT_DIR
	@mkdir -p $(dir $@)
    endif
	$(A_CC) $(C_C_FLAG) $(C_FLAGS)  $(INCLUDES_DIRS) \
                  $(call DBGFILEID,$<) $(SRC_FILE) $(OFLAG) $(OUT_FILE)

$(O_THUMB_FILES): $(OUTPUT_DIR)%.o : $(ROOT_DIR_PAT)%.c
	@$(COL_COMP); echo -n $(DECO); $(COL_RESET); echo "Compiling ... $<"
    ifdef OUTPUT_DIR
	@mkdir -p $(dir $@)
    endif
	$(T_CC) $(C_C_FLAG) $(C_FLAGS)  $(INCLUDES_DIRS) \
                 $(call DBGFILEID,$<) $(SRC_FILE) $(OFLAG) $(OUT_FILE)

$(O_ASM_FILES): $(OUTPUT_DIR)%.o : $(ROOT_DIR_PAT)%.s
	@$(COL_COMP); echo -n $(DECO); $(COL_RESET); echo "Compiling ... $<"
    ifdef OUTPUT_DIR
	@mkdir -p $(dir $@)
    endif
	$(ASM) $(ASM_C_FLAG) $(ASM_FLAGS) $(INCLUDES_DIRS) $(SRC_FILE) $(OFLAG) $(OUT_FILE)


#=============================
#
# $(D_CFILES)
# $(D_ASMFILES)
#
#=============================
ifdef MAKE_DEPEND
$(D_CFILES): $(OUTPUT_DIR)%.d: $(ROOT_DIR_PAT)%.c
    ifdef OUTPUT_DIR
	@mkdir -p $(dir $@)
    endif
	rm -f $@; $(CC_DEP) $(INCLUDES_DIRS) $(C_DEP_CMD)
	$(FIX_DEPEND); touch -d "$(RIGHT_TIME)" $@

$(D_ASMFILES): $(OUTPUT_DIR)%.d: $(ROOT_DIR_PAT)%.s
    ifdef OUTPUT_DIR
	@mkdir -p $(dir $@)
    endif
	$(ASM) $(INCLUDES_DIRS) $(ASM_DEP_CMD)
	@rm -f $(basename $@).o
	$(FIX_DEPEND); touch -d "$(RIGHT_TIME)" $@

endif




#=============================
#
# clean:
#
#=============================
ifndef OUTPUT_DIR
clean: hello clean_text $(LIBS_CLEAN)
	@rm -f -r $(OUTDIR_FULL)
	@rm -f $(O_ARM_FILES)
	@rm -f $(O_THUMB_FILES)
	@rm -f $(O_ASM_FILES)
	@rm -f $(D_CFILES) $(D_ASMFILES)
  ifneq ($(ADD_DEL_FILES),"")
	@rm -f $(ADD_DEL_FILES)
  endif
else
clean: hello clean_text
	@echo $(OUTPUT_CLEAN)
	@rm -r -f $(OUTPUT_CLEAN)
endif

clean_text:
	@$(MAKE) ball TEXT="Cleaning ..." -s  COLOR_BALL="$(COL_CLEAN)"

$(LIBS_CLEAN):
	@$(COL_CLEAN); echo -n $(DECO); $(COL_RESET);
	@echo "Cleaning library ... $(subst _CLEANTAG,,$@)"
	@$(MAKE) -C $(subst _CLEANTAG,,$@) clean NO_HELLO=1 NO_BALL=1


#=============================
#
# $(OUTDIR):
#
#=============================
$(OUTDIR_FULL):
	@mkdir $(OUTDIR_FULL)


#=============================
#
# help & others
#
#=============================
help:
	@echo
	@echo "syntaxt: make <targets> <variables>"
	@echo
	@echo "Targets:"
	@echo "   clean      ... cleans all junks"
	@echo "   compile    ... compiles objects only, no libraries"
	@echo "   libs       ... compiles all libraries and creats archives"
	@echo "   link       ... compiles objects, related libs then links"
	@echo "   bin        ... links and generates a binary output file"
	@echo "   all        ... same as bin"
	@echo "Variables:"
	@echo "   NOCOLORS=1 ... disables colorful output"
	@echo


ball:
ifndef NO_BALL
	@$(COLOR_BALL)                       ;\
        echo    "    ==================="    ;\
        echo    "    ||               ||  "    ;\
        echo -n "    "                      ;\
        $(COL_BALL)                          ;\
        echo    "   $(TEXT)"                 ;\
        $(COLOR_BALL)                        ;\
        echo    "    ||               ||  "  ;\
        echo    "    ===================  "  ;\
        $(COL_RESET)
endif


hello:
ifndef NO_HELLO
	@echo ;\
        $(COL_DECO) ;\
        echo ".....................................................................";\
        echo "---uc make:$(MAKESYSVER)-----------------------------------------------------";\
        echo -n "|| "              ;\
        $(CL_YELLOW);$(CL_BRIGHT)    ;\
        echo -n "NAME ........ "   ;\
        $(CL_WHITE);$(CL_BRIGHT)  ;\
        echo  "$(NAME)"            ;\
        $(COL_DECO);$(CL_BRIGHT)   ;\
        echo -n "|| "              ;\
        $(CL_YELLOW);$(CL_BRIGHT)    ;\
        echo -n "Directory ... "   ;\
        $(CL_WHITE);$(CL_BRIGHT)  ;\
        echo "$(PWD)"              ;\
        echo -n "|| "              ;\
        $(CL_YELLOW);$(CL_BRIGHT)    ;\
        echo -n "SVN Revision. "   ;\
        $(CL_WHITE);$(CL_BRIGHT)  ;\
        echo "$(SVN_REV)"         ;\
        $(COL_DECO)                ;\
        echo "---------------------------------------------------------------------";\
        echo "'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''";\
        $(COL_RESET)
endif





